<?php
/**
 *                    _ooOoo_
 *                   o8888888o
 *                   88" . "88
 *                   (| -_- |)
 *                    O\ = /O
 *                ____/`---'\____
 *              .   ' \\| |// `.
 *               / \\||| : |||// \
 *             / _||||| -:- |||||- \
 *               | | \\\ - /// | |
 *             | \_| ''\---/'' | |
 *              \ .-\__ `-` ___/-. /
 *           ___`. .' /--.--\ `. . __
 *        ."" '< `.___\_<|>_/___.' >'"".
 *       | | : `- \`.;`\ _ /`;.`/ - ` : | |
 *         \ \ `-. \_ __\ /__ _/ .-` / /
 * ======`-.____`-.___\_____/___.-`____.-'======
 *                    `=---='
 *
 * .............................................
 *          佛祖保佑             永无BUG
 */

namespace App\Repositories;


use App\Address;
use App\Distribute;
use App\Exceptions\Interfaces\OrderServiceException;
use App\Good;
use App\Interfaces\OrderService;
use App\Jobs\CreateQrcode;
use App\Jobs\DisTributeSettlement;
use App\Notifications\WechatNotification;
use App\OrderAddress;
use App\OrderCoupon;
use App\OrderGoods;
use App\OrderPay;
use App\User;
use App\UserCoupon;
use App\UserMoneyLog;
use Carbon\Carbon;
use Ramsey\Uuid\Uuid;

class OrderRespository implements OrderService
{
    protected $user;

    public function __construct()
    {
        $this->user = \Auth::user();
    }

    /**
     * @param $cartInfo
     * @return OrderPay
     * @throws OrderServiceException
     * 创建订单
     */

    public function createOrder($cartInfo)
    {
        // dd($cartInfo);
        $orderGoods = [];
        if (empty($cartInfo['cartGoods'])) {
            throw new OrderServiceException('请选择一个商品');
        }
        $total_num = 0;
        $is_rechange = \Auth::user()->can('recharge',Good::first());
        foreach ($cartInfo['cartGoods'] as $k => $v) {
            if ($v['is_sale'] == 1) {
                throw new OrderServiceException($v['goods_name'] . '已下架');
            } elseif ($v['stock'] == 0) {

                throw new OrderServiceException($v['goods_name'] . '已售罄');
            } /*elseif (time() < strtotime($v['sale_start_time'])&&$v['is_recommend']!=1 || time() > strtotime($v['sale_end_time'])&&$v['is_recommend']!=1) {
                       throw new OrderServiceException($v['goods_name'].'不在销售时段');
            }*/ elseif ($v['stock'] < $v['buy_num']) {
                throw new OrderServiceException($v['goods_name'] . '库存不足');
            }
            $orderGoods[$k]['good_id'] = $v['goods_id'];
            $orderGoods[$k]['good_object'] = json_encode($v);
            $total_num += $v['buy_num'];
            $orderGoods[$k]['buy_num'] = $v['buy_num'];
            $orderGoods[$k]['good_price'] = $is_rechange ? $v['repeat_price'] : $v['cost_price'];
            //库存减少操作
            Good::where('id', $v['goods_id'])->decrement('stock', $v['buy_num']);
        }

        //创建订单
        $orderPay = new OrderPay();
        //订单号
        $orderPay->pay_sn = $this->createUuid();
        //用户id
        $orderPay->user_id = $this->user->id;
        $orderPay->pay_price = $cartInfo['price'];
        $orderPay->total_money = $cartInfo['price'];
        $orderPay->total_num = $total_num;
        $orderPay->create_time = Carbon::now();

        $orderPay->save();
        foreach ($orderGoods as &$v) {
            $v['order_pay_id'] = $orderPay->order_pay_id;
        }
        OrderGoods::insert($orderGoods);

        return $orderPay;
    }

    /**
     * @param OrderPay $orderPay
     * 取消订单
     */
    public function cancelOrder(OrderPay $orderPay)
    {
        $orderPay = OrderPay::find($orderPay->order_pay_id);
        if ($orderPay->paid_at || $orderPay->closed) {//支付时间
            return '';
        }
        // \Log::error('订单',$orderPay->toArray());
        \DB::transaction(function () use ($orderPay) {
            $orderPay->closed = 1;
            User::where('id', $orderPay->user_id)->increment('money', $orderPay->pay_balance);
            $orderPay->save();
            $orderGoods = OrderGoods::where('order_pay_id', $orderPay->order_pay_id)->get();
            foreach ($orderGoods as $good) {
                Good::where('id', $good->good_id)->increment('stock', $good->good_object['buy_num']);
            }
            $this->checkIsRecharge(User::find($orderPay->user_id));
            //退还优惠券
           $orderCoupon= OrderCoupon::where('order_pay_id',$orderPay->order_pay_id)->first();
           if($orderCoupon){
             $userCoupon=  UserCoupon::find($orderCoupon->coupon_id);
             $userCoupon->staus=0;
             $userCoupon->save();
           }


        });
    }

    protected function checkIsRecharge(User $user)
    {
        $count = OrderPay::where('closed', '!=', true)
            ->where('pay_status', 1)
            ->where('refund_status', '!=', OrderPay::REFUND_STATUS_APPLIED)
            ->where('user_id', $user->id)
            ->count('order_pay_id');
        if ($count > 0) {
            $user->is_recharge = 1;
        } else {
            $user->is_recharge = 0;
        }
        $user->save();
        return $user;
    }

    /**
     * @param $orderId
     * 查询订单详情
     */
    public function OrderDetail($orderId)
    {
        $orderPay = OrderPay::with(['goods', 'coupons', 'address'])->where('order_pay_id', $orderId)->first();
        if (!$orderPay) {
            abort(404);
        }

        return $orderPay;
    }

    /**
     * @param Address $address
     * 绑定地址
     */
    public function bindAddress(Address $address, OrderPay $orderPay)
    {
        \DB::transaction(function () use ($address, $orderPay) {
            $orderAddress = new OrderAddress();
            $orderAddress->address_id = $address->address_id;
            //   $orderAddress->address_object=$address->toJson();
            $orderAddress->mobile = $address->mobile;
            $orderAddress->address = $address->address;
            $orderAddress->consignee = $address->consignee;
            $orderAddress->province = $address->province;
            $orderAddress->country = $address->country;
            $orderAddress->city = $address->city;
            $orderAddress->district = $address->district;
            $orderAddress->save();
            $orderPay->address_id = $orderAddress->id;
            $orderPay->save();
        });
    }

    /**
     * 绑定优惠券
     * $coupon_id userCoupon 表的Id
     */
    public function bindCoupon($coupon_id, OrderPay $orderPay)
    {
        if(!$coupon_id){
          $orderCoupon=  OrderCoupon::where('order_pay_id',$orderPay->order_pay_id)->first();
          if($orderCoupon){
            $orderPay->pay_price=$orderPay->pay_price+$orderCoupon->coupon_object['money'];
            $orderPay->save();
            $orderCoupon->delete();
          }else{
              return $orderPay;
          }
        }
        $orderCoupon=  OrderCoupon::where('order_pay_id',$orderPay->order_pay_id)->first();

        if($orderCoupon){
            $userCoupon=UserCoupon::with('coupon')->where('id',$orderCoupon->coupon_id)->first();
            if (!$userCoupon) {
                throw  new  OrderServiceException('查不到优惠券信息');
            }
        }else {

            $userCoupon = UserCoupon::with('coupon')->where('user_id', \Auth::id())->where('staus', 0)->where('conpon_id', $coupon_id)->first();
            //  dd($userCoupon);
            if (!$userCoupon) {
                throw  new  OrderServiceException('查不到优惠券信息');
            }
            if (!isset($userCoupon->coupon)) {
                throw  new OrderServiceException('优惠券已删除');
            }
            if ($userCoupon->coupon->start_time > Carbon::now() || $userCoupon->coupon->end_time < Carbon::now()) {
                throw  new OrderServiceException('优惠券未在使用期限');
            }
            if ($userCoupon->staus == 1) {
                throw new OrderServiceException('优惠券已使用');
            }
        }
        //绑定操作
        \DB::transaction(function () use ($userCoupon, $orderPay) {
            $orderCoupon=OrderCoupon::where('order_pay_id',$orderPay->order_pay_id)->first();
            if(!$orderCoupon){
                $userCoupon->staus = 1;
                $userCoupon->save();
                $orderCoupon = new OrderCoupon();
                $orderCoupon->coupon_id = $userCoupon->id;
                $orderCoupon->coupon_object = $userCoupon->coupon->toJson();
                $orderCoupon->order_pay_id = $orderPay->order_pay_id;
                $orderCoupon->save();
                $price = $orderPay->pay_price - $userCoupon->coupon->money < 0 ? 0 : $orderPay->pay_price - $userCoupon->coupon->money;
                $orderPay->pay_price = $price;
                $orderPay->save();
            }else{
                $userOldCoupon= UserCoupon::with('coupon')->where('id',$orderCoupon->coupon_id)->first();
                $userCoupon->staus = 0;
                $userCoupon->save();
                $orderCoupon->coupon_id = $userCoupon->id;
                $orderCoupon->coupon_object = $userCoupon->coupon->toJson();
                $orderCoupon->order_pay_id = $orderPay->order_pay_id;
                $orderCoupon->save();
                $price = $orderPay->pay_price + $userOldCoupon->coupon->money -$userCoupon->coupon->money < 0 ? 0 : $orderPay->pay_price  + $userOldCoupon->coupon->money -$userCoupon->coupon->money;
                $orderPay->pay_price = $price;
                $orderPay->save();

            }
           
        });

        return $orderPay;
    }

    /**
     * 创建uuid
     * @return string
     */
    private function createUuid()
    {
//        $data = Uuid::uuid1();
//        return $data->getTimestampHex();
        return 'JD' . date('YmdHis', time()) . rand(100, 999);

    }

    public function OrderHanle(OrderPay $orderPay)
    {

        \DB::transaction(function () use ($orderPay) {
            $orderPay = OrderPay::where('order_pay_id', $orderPay->order_pay_id)->sharedLock()->first();//锁
            if ($orderPay->pay_status == 1) {//判断是否支付
                return true;
            }
            $user = User::with('team')->where('id', $orderPay->user_id)->first();
            //复购
            $user->consume = $user->consume + $orderPay->total_money;//消费额度
            $orderPay->pay_status = 1;
            $orderPay->paid_at = Carbon::now();
            $orderPay->ship_status = OrderPay::SHIP_STATUS_SURE_ORDER;//未发货

            //查看用户推广的上级列表
            $teamList = $user->team_path;
            array_shift($teamList);
            $sort = implode(',', $teamList);
            if (count($teamList) > 0) {//查询团队成员
                $teamUsers = User::with('team')->whereIn('id', $teamList)->orderBy(\DB::raw("find_in_set(id,'$sort')"), 'asc')->get();
                //分销比例
                $distribute = Distribute::find(1);
                $first_distribute = $user->is_recharge ? $distribute->first_recharge : $distribute->first;
                $second_distribute = $user->is_recharge ? $distribute->second_recharge : $distribute->second;
                //users 用户列表
                $users = [];
                $userRepository = new UserRepository();
                foreach ($teamUsers as $k => $v) {
                    if ($k == 0) {//直推一级分销
                        $price = $orderPay->total_money * $first_distribute / 100;
                    } elseif ($k == 1) {
                        $price = $orderPay->total_money * $second_distribute / 100;
                    } else {
                        break;
                    }
                    if ($price > 0) {
                        $userDistribution = User::find($v->id);
                        $userDistribution->distribution_money += $price;
                        $userDistribution->distribution_total_sale += $orderPay->total_money;
                        $users = array_merge($users, [$userDistribution->id]);

                        $userDistribution->save();
                        $userMoneyLog = new UserMoneyLog();
                        $userMoneyLog->price = $price;
                        $userMoneyLog->user_id = $orderPay->user_id;
                        $userMoneyLog->order_pay_id = $orderPay->order_pay_id;
                        $userMoneyLog->type = 0;
                        $userMoneyLog->leader_id = $v->id;
                        $userMoneyLog->save();
                        //通知
                        $userDistribution->notify(new WechatNotification("您的粉丝(昵称:{$user->name},会员编号:{$user->id})订购产品成功\n订单号:{$orderPay->pay_sn}\n金额:{$orderPay->total_money}\n您有分享佣金:{$price}元\n祝贺一下"));
                    }
                }
                //团队推广
                $rate = 0;//初次分成比例
                $lastRate = 0;//当前已分成比例
                foreach ($teamUsers as $k => $v) {
                    //判断是否需要分成
                    if ($v->team->reward > $user->team->reward) {
                        $rate = $v->team->reward - $lastRate;
                    }
                    if ($rate > 0 && $v->team->reward > $user->team->reward) {
                        //执行利润分配

                        //   \Log::error($v->id,[$rate]);
                        $price = $rate * $orderPay->total_money / 100;
                        $userTeam = User::find($v->id);
                        $userTeam->team_money += $price;
                        if (!in_array($v->id, $users)) {
                            $userTeam->distribution_total_sale += $orderPay->total_money;
                        }
                        $userTeam->save();
                        $userMoneyLog = new UserMoneyLog();
                        $userMoneyLog->price = $price;
                        $userMoneyLog->user_id = $orderPay->user_id;
                        $userMoneyLog->order_pay_id = $orderPay->order_pay_id;
                        $userMoneyLog->type = 1;
                        $userMoneyLog->leader_id = $v->id;
                        $userMoneyLog->save();
                        $lastRate = $v->team->reward;
                        //  \Log::error($v->id.'哈',[$rate]);
                        //检查是否升级

                        $userTeam->notify(new WechatNotification("您的粉丝(昵称:{$user->name},会员编号:{$user->id})订购产品成功\n订单号:{$orderPay->pay_sn}\n金额:{$orderPay->total_money}\n您有社群销售奖励:{$price}元\n祝贺一下"));
                    } else {
                        //   $rate=$v->team->reward;
                    }
                }
                foreach ($teamUsers as $v) {
                    $userRepository->checkTeamLeavel(User::find($v->id));
                }

            }

            //更改用户状态为复购
            if ($user->is_recharge != 1) {
                $user->is_recharge = 1;
                $orderPay->is_recharge = 0;
            } else {
                $orderPay->is_recharge = 1;
            }
            if ($user->team_level_id == 0) {
                $user->team_level_id = 1;
                $user->save();
              $userRepository = new UserRepository();
                $userRepository->team_level_notice($user);
            }

            $user->save();
            //用户通知
            $user->notify(new WechatNotification("您的订单($orderPay->pay_sn,金额:$orderPay->total_money) 于 {$orderPay->paid_at}支付成功。\n我们将尽快为您发货，订单状态请在个人中心查阅.\n给您++幸福++啦"));
            //修复已支付 但订单关闭的情况
            $orderPay->closed = 0;
            $orderPay->save();
        }, 1);

        return true;
    }

    /**
     * 订单列表
     */
    public function orderList()
    {

    }

    /**
     * @param OrderPay $orderPay
     * 确认订单
     */
    public function sureOrder(OrderPay $order)
    {
        \DB::transaction(function () use ($order) {
            // 判断订单的发货状态是否为已发货
            if ($order->ship_status !== OrderPay::SHIP_STATUS_DELIVERED) {
                throw new OrderServiceException('发货状态不正确');
            }
            $order->ship_status = OrderPay::SHIP_STATUS_RECEIVED;
            $order->save();
            $userMoneyLog = UserMoneyLog::where('order_pay_id', $order->order_pay_id)->where('status', 0)->get();
            if ($userMoneyLog->isNotEmpty()) {
                foreach ($userMoneyLog as $v) {
                    dispatch(new DisTributeSettlement($v, config('app.settlement')));
                }
            }

        });
    }

    /**
     * 订单退款
     */
    public function refundOrder(OrderPay $orderPay)
    {


        \DB::transaction(function () use ($orderPay) {

            $orderPay = OrderPay::where('order_pay_id', $orderPay->order_pay_id)->sharedLock()->first();//锁
            if ($orderPay->pay_status != 1 || $orderPay->refund_status==OrderPay::REFUND_STATUS_APPLIED) {
                throw  new OrderServiceException('订单已经退款');
            }
            if ($orderPay->pay_type == OrderPay::PAY_BALANCE) {
                User::where('id', $orderPay->user_id)->increment('money', $orderPay->pay_price);
            } elseif ($orderPay->pay_type == OrderPay::PAY_WECHAT) {
                $this->refundByWechat($orderPay);
            } elseif ($orderPay->pay_type == OrderPay::PAY_ALI) {
                $this->refundByAliPay($orderPay);
            }
            //返还用户金额支付的部分
            User::where('id', $orderPay->user_id)->increment('money', $orderPay->pay_balance);
            //增加商品库存
            $goods = $orderPay->goods;
            foreach ($goods as $v) {
                Good::where('id', $v->good_id)->increment('stock', $v->buy_num);
            }
            //删除推广收益
            $userMoneyLog = UserMoneyLog::where('order_pay_id', $orderPay->order_pay_id)->get();
            //减少用户推广收益金额
            $userRepository = new UserRepository();
            $users = [];
            foreach ($userMoneyLog as $v) {

                if ($v->type == 0) {
                    $userTeam = User::where('id', $v->leader_id)->first();
                    $userTeam->distribution_money = $userTeam->distribution_money - $v->price;
                } else {
                    $userTeam = User::where('id', $v->leader_id)->first();
                    $userTeam->team_money = $userTeam->team_money - $v->price;
                }
                if (!in_array($userTeam->id, $users)) {
                    //减少订单收益
                    $userTeam->distribution_total_sale = $userTeam->distribution_total_sale - $orderPay->total_money;
                    $users = array_merge($users, [$userTeam->id]);
                }
                $userTeam->save();
                $v->status = 1;
                $v->save();
                //写入退款流水
                $userMoney = new UserMoneyLog();
                $userMoney->type = $v->type;
                $userMoney->user_id = $v->user_id;
                $userMoney->leader_id = $v->leader_id;
                $userMoney->price = $v->price;
                $userMoney->order_pay_id = $v->order_pay_id;
                $userMoney->status = 1;
                $userMoney->refund_status = UserMoneyLog::REFUND_STATUS_APPLIED;
                $userMoney->save();
                $userRepository->checkTeamLeavelReduce($userTeam);
            }

            $orderPay->refund_status = OrderPay::REFUND_STATUS_APPLIED;
            $orderPay->ship_status = OrderPay::SHIP_STATUS_CLOSED;
            $orderPay->refund_time = Carbon::now();
            $orderPay->save();
            //检查用户是否是有支付的订单 判断是否首购
            $firstRecharge = OrderPay::where('user_id', $orderPay->user_id)
                ->where('pay_status', 1)
                ->where('refund_status', '!=', OrderPay::REFUND_STATUS_APPLIED)
                ->count('order_pay_id');
            $user = User::where('id', $orderPay->user_id)->first();
            if ($firstRecharge == 0) {
                $user->is_recharge = 0;
                //查看user是否是会员
                $user->team_level_id = $user->team_level_id == 1 ? 0 : $user->team_level_id;
            }
            //消除消费额度
            $user->consume = $user->consume - $orderPay->total_money;
            $user->save();
        }, 2);
    }

    /**
     * @param $pay_sn
     * 微信退款
     */
    protected function refundByWechat(OrderPay $orderPay)
    {
        $app = \EasyWeChat::payment();
        $refund_no = $this->createUuid();
        $orderPay->refund_no = $refund_no;
        $orderPay->save();
        $result = $app->refund->byOutTradeNumber($orderPay->pay_sn, $refund_no, ($orderPay->pay_price - $orderPay->pay_balance) * 100, ($orderPay->pay_price - $orderPay->pay_balance) * 100, [
            'refund_desc' => '商品退货',
        ]);
        \Log::error('微信退款',$result);
        if ($result['return_code'] == 'FAIL') {
            \Log::error('微信退款', $result);
            throw  new OrderServiceException($result['return_msg']);
        }
        if ($result['result_code'] == 'FAIL') {
            \Log::error('微信退款', $result);
            throw  new OrderServiceException($result['err_code_des']);
        }

    }

    //订单补缴分享佣金
    public function teamHandle(User $user, OrderPay $orderPay)
    {
        //查看用户推广的上级列表
        $teamList = $user->team_path;
        array_shift($teamList);
        $sort = implode(',', $teamList);
        if (count($teamList) > 0) {//查询团队成员
            $teamUsers = User::with('team')->whereIn('id', $teamList)->orderBy(\DB::raw("find_in_set(id,'$sort')"), 'asc')->get();
            //分销比例
            $distribute = Distribute::find(1);
            $first_distribute = $orderPay->is_recharge ? $distribute->first_recharge : $distribute->first;
            $second_distribute = $orderPay->is_recharge ? $distribute->second_recharge : $distribute->second;
            //users 用户列表
            $users = [];
            $userRepository = new UserRepository();
            foreach ($teamUsers as $k => $v) {
                if ($k == 0) {//直推一级分销
                    $price = $orderPay->total_money * $first_distribute / 100;
                } elseif ($k == 1) {
                    $price = $orderPay->total_money * $second_distribute / 100;
                } else {
                    break;
                }
                if ($price > 0) {
                    $userDistribution = User::find($v->id);
                    $userDistribution->distribution_money += $price;
                    $userDistribution->distribution_total_sale += $orderPay->total_money;
                    $users = array_merge($users, [$userDistribution->id]);

                    $userDistribution->save();
                    $userMoneyLog = UserMoneyLog::where('order_pay_id', '=', $orderPay->order_pay_id)->where('leader_id', $v->id)->where('type',0)->first();
                    if (!$userMoneyLog) {
                        $userMoneyLog = new UserMoneyLog();
                    }
                    $userMoneyLog->price = $price;
                    $userMoneyLog->user_id = $orderPay->user_id;
                    $userMoneyLog->order_pay_id = $orderPay->order_pay_id;
                    $userMoneyLog->type = 0;
                    $userMoneyLog->leader_id = $v->id;
                    $userMoneyLog->save();

                    //通知
                    $userDistribution->notify(new WechatNotification("您的粉丝(昵称:{$user->name},会员编号:{$user->id})订购产品成功\n订单号:{$orderPay->pay_sn}\n金额:{$orderPay->total_money}\n您有分享佣金:{$price}元\n祝贺一下"));
                }
            }
            //团队推广
            $rate = 0;//初次分成比例
            $lastRate = 0;//当前已分成比例
            foreach ($teamUsers as $k => $v) {
                //判断是否需要分成
                if ($v->team->reward > $user->team->reward) {
                    $rate = $v->team->reward - $lastRate;
                }
                if ($rate > 0 && $v->team->reward > $user->team->reward) {
                    //执行利润分配

                    //   \Log::error($v->id,[$rate]);
                    $price = $rate * $orderPay->total_money / 100;
                    $userTeam = User::find($v->id);
                    $userTeam->team_money += $price;
                    if (!in_array($v->id, $users)) {
                        $userTeam->distribution_total_sale += $orderPay->total_money;
                    }
                    $userTeam->save();
                    $userMoneyLog = UserMoneyLog::where('order_pay_id', '=', $orderPay->order_pay_id)->where('leader_id', $v->id)->where('type',1)->first();
                    if (!$userMoneyLog) {
                        $userMoneyLog = new UserMoneyLog();
                    }
                    $userMoneyLog->price = $price;
                    $userMoneyLog->user_id = $orderPay->user_id;
                    $userMoneyLog->order_pay_id = $orderPay->order_pay_id;
                    $userMoneyLog->type = 1;
                    $userMoneyLog->leader_id = $v->id;
                    $userMoneyLog->save();
                    $lastRate = $v->team->reward;
                    //  \Log::error($v->id.'哈',[$rate]);
                    //检查是否升级

                    $userTeam->notify(new WechatNotification("您的粉丝(昵称:{$user->name},会员编号:{$user->id})订购产品成功\n订单号:{$orderPay->pay_sn}\n金额:{$orderPay->total_money}\n您有社群销售奖励:{$price}元\n祝贺一下"));
                } else {
                    //   $rate=$v->team->reward;
                }
            }
            foreach ($teamUsers as $v) {
                $userRepository->checkTeamLeavel(User::find($v->id));
            }

        }
    }

    protected function refundByAliPay(OrderPay $orderPay)
    {
        $app = app('alipay');
        $refund_no = $this->createUuid();
        $orderPay->refund_no = $refund_no;
        $orderPay->save();
        $app->refund([
            'out_trade_no' => $orderPay->pay_sn,
            'refund_amount' => $orderPay->pay_price - $orderPay->pay_balance,
            'out_request_no' => $refund_no
        ]);
        if (!$app->msg == 'Success') {
            throw  new OrderServiceException('支付宝退款异常，请联系管理员');
        }
    }

}